#include "GAF_Image.h"
#include "GAF_Platform.h"

namespace GAF
{
	Image::ImageList Image::ms_lstImages;

	Image* Image::Create()
	{
		Image* _pimgNew = GAF_NEW(Image);
		ms_lstImages.push_back(_pimgNew);
		return _pimgNew;
	}

	Image* Image::Create(const STD_STRING strPathName)
	{
		Image* _pimgNew = GAF_NEW(Image);

		if(_pimgNew->SetImageHandle(strPathName))
		{
			ms_lstImages.push_back(_pimgNew);
		}
		else
		{
			GAF_DELETE(_pimgNew);
			_pimgNew = NULL;
		}

		return _pimgNew;
	}

	Image* Image::Create(Package* pPackage, const STD_STRING strImageName)
	{
		GAF_CHECK_R(pPackage != NULL, NULL);
		GAF_CHECK_R(strImageName != "", NULL);

		Image* _pimgNew = GAF_NEW(Image);

		if(_pimgNew->SetImageHandle(pPackage, strImageName))
		{
			ms_lstImages.push_back(_pimgNew);
		}
		else
		{
			GAF_DELETE(_pimgNew);
			_pimgNew = NULL;
		}

		return _pimgNew;
	}

	Image* Image::Create(const ImageHandle hImage, const ImageInfo& ii)
	{
		GAF_CHECK_R(hImage != NULL, NULL);

		Image* _pimgNew = GAF_NEW(Image);

		if(_pimgNew->SetImageHandle(hImage, ii))
		{
			ms_lstImages.push_back(_pimgNew);
		}
		else
		{
			GAF_DELETE(_pimgNew);
			_pimgNew = NULL;
		}

		return _pimgNew;
	}

	Image* Image::Create(const UINT nWidth, const UINT nHeight)
	{
		Image* _pimgNew = GAF_NEW(Image);

		if(_pimgNew->SetImageHandle(nWidth, nHeight))
		{
			ms_lstImages.push_back(_pimgNew);
		}
		else
		{
			GAF_DELETE(_pimgNew);
			_pimgNew = NULL;
		}

		return _pimgNew;
	}

	bool Image::Destroy(Image* pimgOne)
	{
		GAF_CHECK_R(pimgOne != NULL, false);

		ms_lstImages.remove(pimgOne);

		GAF_DELETE(pimgOne);

		return true;
	}

	bool Image::DestroyAll()
	{
		if(ms_lstImages.size() > 0)
		{
			Image* _pimg = NULL;

			for(ImageList::const_iterator _cit = ms_lstImages.begin();
				_cit != ms_lstImages.end(); _cit++)
			{
				_pimg = *_cit;
				GAF_DELETE(_pimg);
			}
			ms_lstImages.clear();
		}

		return true;
	}

	int Image::GetLinkCount()
	{
		return ms_lstImages.size();
	}



	Image::Image()
	{
		m_nGType	= GRAPHICS_IMAGE;
		ATTRIB(Clip)	= GAF_RECT_NULL;
		m_hImage	= NULL;
		m_hTransform	= NULL;
		m_isOwn	= false;

		memset(&m_iiOriginal, 0, sizeof(ImageInfo) - sizeof(Bundle));
	}

	Image::~Image()
	{
		Release();
	}

	bool Image::SetImageHandle(const STD_STRING strPathFile)
	{
		ImageHandle _hImage = GAF_pTHEPLATFORM->NewImage(strPathFile, GetImageInfo_a());

		if(_hImage == NULL)
			return false;

		Release();
		m_hImage = _hImage;
		m_isOwn = true;

		SetSize(GetImageInfo_a().nWidth, GetImageInfo_a().nHeight);

		// 标明资源来源
		STD_STRING _strForm = "File_";
		_strForm += strPathFile;
		AddInfos()->PutString(GAF_INFO_IMAGEFROM, _strForm);

//		SetClip(0, 0, GAF_ARG_SIZE(GetSize_a()));

		return true;
	}

	bool Image::SetImageHandle(Package* pPackage, const STD_STRING strImageName)
	{
		GAF_ASSERT(pPackage != NULL);

		ImageHandle _hImage = pPackage->GetImageHandle(strImageName, GetImageInfo_a());

		if(_hImage == NULL)
			return false;

		Release();
		m_hImage = _hImage;
		m_isOwn = false;

		SetSize(GetImageInfo_a().nWidth, GetImageInfo_a().nHeight);

		// 标明资源来源
		STD_STRING _strForm = "Package_";
		STD_STRING _strPath = pPackage->GetPath();
		_strForm += _strPath;
		_strForm += "_";
		_strForm += strImageName;
		AddInfos()->PutString(GAF_INFO_IMAGEFROM, _strForm);

//		SetClip(0, 0, GAF_ARG_SIZE(GetSize_a()));

		return true;
	}

	bool Image::SetImageHandle(const ImageHandle hImage, const ImageInfo& ii)
	{
		GAF_CHECK_R(hImage != NULL, false);

		Release();
		m_hImage = hImage;
		m_isOwn = false;

		// 标明资源来源
		char _sz[20];
		SYS_SPRINTF(_sz, "Handle_%d", hImage);
		AddInfos()->PutString(GAF_INFO_IMAGEFROM, _sz);

		SetSize(ii.nWidth, ii.nHeight);
		CopyImageInfo(ii);
//		SetClip(0, 0, GAF_ARG_SIZE(GetSize_a()));

		return true;
	}

	bool Image::SetImageHandle(const UINT nWidth, const UINT nHeight)
	{
		ImageHandle _hImage = GAF_pTHEPLATFORM->NewImage(nWidth, nHeight, m_iiOriginal);

		if(_hImage == NULL)
			return false;

		Release();
		m_hImage = _hImage;
		m_isOwn = true;

		static int _nMemID = 0;
		STD_STRING _strForm = "Memory_";
		_strForm += _nMemID++;
		AddInfos()->PutString(GAF_INFO_IMAGEFROM, _strForm);

		SetSize(nWidth, nHeight);
//		SetClip(0, 0, GAF_ARG_SIZE(GetSize_a()));

		return true;
	}

	ImageHandle Image::GetImageHandle(bool bIsTransform)
	{
		if(!bIsTransform)
			return m_hImage;

		return (m_hTransform == NULL) ? m_hImage : m_hTransform;
	}

	bool Image::CopyImage(Image* pimgDis, int nX, int nY, UINT nWidth, UINT nHeight)
	{
		GAF_CHECK_R(pimgDis != NULL, false);

		Release();
		m_hImage = pimgDis->GetImageHandle();
		CopyImageInfo(pimgDis->GetImageInfo_a());
		SetSize_a(pimgDis->GetSize_a());
		SetClip(nX, nY, nWidth, nHeight);

		return true;
	}

	void Image::CopyImageInfo(const ImageInfo& iiOther)
	{
		m_iiOriginal.nWidth = iiOther.nWidth;
		m_iiOriginal.nHeight = iiOther.nHeight;
		m_iiOriginal.nBitsPixel = iiOther.nBitsPixel;

		m_iiOriginal.bdlOther.Copy(&(iiOther.bdlOther));
	}

 	void Image::SetTransparent(float fTransparent)
 	{
 		if(fTransparent > 0.0f)
 		{
 			if(fTransparent > 100.0f)
 				fTransparent = 100.0f;
 			float _fAlpha = 255.0f / 100 * fTransparent;
 			SetAlpha_a((unsigned char)_fAlpha);
 		}
 	}

	void Image::SetClip(int nX, int nY, UINT nWidth, UINT nHeight)
	{
		Rect _rect;
		_rect.nX = nX;
		_rect.nY = nY;
		_rect.nWidth = nWidth;
		_rect.nHeight = nHeight;

		SetClip_a(_rect);
	}

	void Image::Release()
	{
		if(m_isOwn && m_hImage != NULL)
			GAF_pTHEPLATFORM->DeleteImage(m_hImage);
		m_hImage = NULL;

		if(m_hTransform != NULL)
			GAF_pTHEPLATFORM->DeleteImage(m_hTransform);
		m_hTransform = NULL;

		m_iiOriginal.nWidth = 0;
		m_iiOriginal.nHeight = 0;
		m_iiOriginal.nBitsPixel = 0;
		m_iiOriginal.bdlOther.Clear();

		m_isOwn = false;
	}
}
